
import org.rsbot.script.*;
import org.rsbot.script.wrappers.*;
import org.rsbot.script.methods.Bank;
import org.rsbot.event.listeners.*;
import org.rsbot.script.methods.GrandExchange.GEItem;
import org.rsbot.script.wrappers.RSPath.TraversalOption;

import java.io.*;
import java.net.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

@ScriptManifest(authors = "icnhzabot , Aut0r", name = "Aut0Filler", version = 2.3, description = "Fills empty containers at multiple locations!", website = "http://www.aut0rprogramming.net")
public class Aut0Filler extends Script implements PaintListener {

    private boolean end;
    private String scriptName = "Aut0Filler";
    private double version = 2.30;
    private int emptyPrice = -1;
    private int fullPrice = -1;
    private GUI gui;
    private locations locations;
    private RSTile last;
    private boolean canAntiBan = true;
    private item item;
    private boolean running = true;
    private int numDone = 0;
    private UtilThread utilThread = null;
    private boolean string;
    private int mouseLo = 10, mouseHi = 5;
    private loopVoids loopVoids;
    private CameraMovementChecker cameraChecker;
    private MouseMovementChecker mouseChecker;
    private AntiBan antiBan;
    private Timekeeper timekeeper = new Timekeeper();

    private enum State {

        CLOSE_BANK, CLOSE_COLLECTION, OPEN_BANK, WITHDRAW, DEPOSIT, CLICK_CONTINUE, WALK_BANK, FILL_ITEMS, WALK_WATER, WAIT, STOP;
    }

    private State getState() {
        if (isPaused() || !isActive() || !isRunning() || !game.isLoggedIn() || game.isWelcomeScreen() || game.isLoginScreen()) {
            return State.WAIT;
        }
        if (interfaces.getComponent(109, 1).isValid() || interfaces.getComponent(109, 0).isValid() || interfaces.getComponent(109, 2).isValid() || interfaces.getComponent(109, 14).isValid() || interfaces.getComponent(Bank.INTERFACE_COLLECTION_BOX).isValid()) {
            return State.CLOSE_COLLECTION;
        }
        if (locations.waterArea().contains(getMyPlayer().getLocation())) {
            if (utilThread.getIdle() >= 8) {
                if (inventory.contains(item.emptyID())) {
                    return State.FILL_ITEMS;
                } else {
                    return State.WALK_BANK;
                }
            }
        } else if (locations.bankArea().contains(getMyPlayer().getLocation())) {
            if (bank.isOpen()) {
                if (inventory.contains(item.fullID())) {
                    return State.DEPOSIT;
                } else if (!inventory.contains(item.emptyID())) {
                    if (bank.getCount(item.emptyID()) <= 0) {
                        return State.STOP;
                    } else {
                        return State.WITHDRAW;
                    }
                }
                if (inventory.contains(item.emptyID()) && !inventory.contains(item.fullID())) {
                    return State.CLOSE_BANK;
                }
            } else {
                if ((inventory.contains(item.fullID()) || !inventory.contains(item.emptyID())) && !bank.isOpen() && !getMyPlayer().isMoving()) {
                    return State.OPEN_BANK;
                } else if (inventory.contains(item.emptyID()) && !getMyPlayer().isMoving() && !bank.isOpen()) {
                    return State.WALK_WATER;
                }
            }
        }
        if (!locations.waterArea().contains(getMyPlayer().getLocation()) && !locations.bankArea().contains(getMyPlayer().getLocation())) {
            if (!getMyPlayer().isMoving()) {
                sleep(200);
                if (!getMyPlayer().isMoving()) {
                    sleep(100);
                    if (!getMyPlayer().isMoving()) {
                        if (inventory.contains(item.emptyID())) {
                            return State.WALK_WATER;
                        } else {
                            return State.WALK_BANK;
                        }
                    }
                }
            }
        }
        return State.WAIT;
    }

    @Override
    public boolean onStart() {
        if (!game.isFixed()) {
            log.severe("Please run with a fixed screen size");
            return false;
        }
        log("Welcome to Aut0Filler");
        running = true;
        gui = new GUI();
        gui.setVisible(true);
        while (gui.isVisible()) {
            sleep(100);
        }
        sleep(50);
        if (gui.isCancelled()) {
            return false;
        }
        int location = gui.getItemLocation();
        switch (location) {
            case 0: {
                locations = new FaladorWest();
                string = true;
            }
            break;
            case 1: {
                locations = new alKharid();
                string = false;
            }
            break;
            default: {
                string = false;
                return false;
            }
        }
        mouseLo = gui.getMouseLo();
        mouseHi = gui.getMouseHi();
        log("Getting item prices, this may take a moment...");
        item = new item(229, 227);
        utilThread = new UtilThread();
        loopVoids = new loopVoids();
        antiBan = new AntiBan();
        mouseChecker = new MouseMovementChecker();
        cameraChecker = new CameraMovementChecker();
        GEItem empty = grandExchange.lookup(item.emptyID());
        GEItem full = grandExchange.lookup(item.fullID());
        if (empty == null || full == null) {
            log("Failure getting item prices.");
            return false;
        }
        emptyPrice = empty.getGuidePrice();
        fullPrice = full.getGuidePrice();
        if (emptyPrice == -1 || fullPrice == -1) {
            log("Failure getting item prices. Please try again.");
            return false;
        }
        log("Done. Empty Item Price: " + emptyPrice + ". Full Item Price: " + fullPrice);
        return true;
    }

    @Override
    public int loop() {
        if (!running) {
            running = true;
        }
        try {
            if (random(1, 3) == 3) {
                mouse.setSpeed(random(mouseLo, mouseHi));
            }
            final State state = getState();
            switch (state) {
                case CLOSE_BANK: {
                    if (!loopVoids.closeBank()) {
                        return 5;
                    }
                    break;
                }
                case CLOSE_COLLECTION: {
                    if (!loopVoids.closeCollection()) {
                        return 5;
                    }
                    break;
                }
                case OPEN_BANK: {
                    if (!loopVoids.openBank()) {
                        return 5;
                    }
                    break;
                }
                case WITHDRAW: {
                    if (!loopVoids.withdraw()) {
                        return 5;
                    }
                    break;
                }
                case DEPOSIT: {
                    if (!loopVoids.deposit()) {
                        return 5;
                    }
                    break;
                }
                case CLICK_CONTINUE: {
                    if (!loopVoids.clickContinue()) {
                        return 5;
                    }
                    break;
                }
                case WALK_BANK: {
                    if (!loopVoids.walkBank()) {
                        return 5;
                    }
                    break;
                }
                case FILL_ITEMS: {
                    if (!loopVoids.fillItems()) {
                        return 5;
                    }
                    break;
                }
                case WALK_WATER: {
                    if (!loopVoids.walkWater()) {
                        return 5;
                    }
                    break;
                }
                case WAIT: {
                    sleep(random(80, 120));
                    return 5;
                }
                case STOP: {
                    loopVoids.stop();
                    break;
                }
            }
        } catch (Exception e) {
        }
        return random(100, 300);
    }

    @Override
    public void onFinish() {
        running = false;
        log("Thank you for using!");
    }

    @Override
    public void onRepaint(Graphics g1) {
        if (isPaused() || !isActive() || !isRunning() || !game.isLoggedIn() || game.isLoginScreen() || game.isWelcomeScreen()) {
            if (timekeeper.getState() == 0) {
                timekeeper.setPaused();
            }
        } else {
            if (timekeeper.getState() == 1) {
                timekeeper.setResumed();
            }
        }
        final RenderingHints antialiasing = new RenderingHints(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        final Color color1 = new Color(0, 0, 255, 108);
        final Color color2 = new Color(0, 0, 0);
        final Color color3 = new Color(255, 255, 255);
        final Color transGreen = new Color(0, 255, 0, 125);
        final Color transRed = new Color(255, 0, 0, 125);
        final BasicStroke stroke1 = new BasicStroke(1);
        Graphics2D g = (Graphics2D) g1;
        g.setRenderingHints(antialiasing);

        g.setColor(color1);
        g.fillRoundRect(10, 125, 300, 205, 16, 16);
        g.setStroke(stroke1);
        g.setColor(color2);
        g.drawRoundRect(10, 125, 300, 205, 16, 16);
        g.setFont(new Font("Calibri", 0, 14));
        g.setColor(color3);
        int idle = (int) utilThread.getIdle();
        String idleString;
        StringBuilder builder = new StringBuilder();
        if (idle > 99) {
            builder.append("+99");
        } else {
            builder.append(idle);
        }
        idleString = builder.toString();
        long totalProfit = (numDone * fullPrice) - (numDone * emptyPrice);
        g.drawString("Idle Monitor: " + idleString, 15, 310);
        g.drawString("Profit/Hr: " + Long.toString(timekeeper.calcPerHour(totalProfit)), 15, 285);
        g.drawString("Total Profit: " + Long.toString(totalProfit), 15, 260);
        g.drawString("Items/Hr: " + Long.toString(timekeeper.calcPerHour(numDone)), 15, 235);
        g.drawString("Items Filled: " + Integer.toString(numDone), 15, 210);
        if (timekeeper.getState() == 0) {
            g.drawString("Runtime: " + timekeeper.getRuntimeString(), 15, 185);
        } else {
            g.drawString("Runtime: Paused", 15, 185);
        }
        g.setFont(new Font("Calibri", 0, 17));
        g.drawString("Aut0Filler", 40, 155);
        g.setFont(new Font("Calibri", 1, 15));
        g.setColor(color2);
        g.drawString("by Aut0r and icnhzabot", 114, 155);
        g.setColor(color3);
        g.setFont(new Font("Calibri", 1, 15));
        g.drawString("www.aut0rprogramming.net", 315, 335);
        if (System.currentTimeMillis() - mouse.getPressTime() <= 175) {
            g.setColor(Color.red);
        } else {
            g.setColor((Color.blue).brighter().darker().brighter());
            g.setColor(g.getColor().brighter().darker().brighter());
        }
        g.setStroke(new BasicStroke(3));
        g.drawLine(mouse.getLocation().x + 12, mouse.getLocation().y, mouse.getLocation().x - 12, mouse.getLocation().y);
        g.drawLine(mouse.getLocation().x, mouse.getLocation().y + 12, mouse.getLocation().x, mouse.getLocation().y - 12);
        if (!g.getColor().equals(Color.red)) {
            g.setStroke(stroke1);
            g.setColor(Color.black);
            g.drawLine(mouse.getLocation().x + 12, mouse.getLocation().y, mouse.getLocation().x - 12, mouse.getLocation().y);
            g.drawLine(mouse.getLocation().x, mouse.getLocation().y + 12, mouse.getLocation().x, mouse.getLocation().y - 12);
        }
        float m = (float) (utilThread.getIdle() * 9.35);
        if (m > 187) {
            m = 187;
        }
        int p = (int) m;
        g.setColor(transGreen);
        g.fillRect(115, 295, 187, 20);
        g.setColor(transRed);
        g.fillRect(115, 295, p, 20);
        g.setColor(color2);
        g.setStroke(stroke1);
        g.drawRect(115, 295, 187, 20);
    }

    private class loopVoids {

        public boolean closeBank() {
            try {
                sleep(random(100, 300));
                if (!locations.closeBank()) {
                    return false;
                }
                sleep(random(100, 300));
            } catch (Exception e) {
                return false;
            }
            return true;
        }

        public boolean closeCollection() {
            try {
                mouse.move(427, 74);
                sleep(random(150, 230));
                if (menu.contains("Close")) {
                    return menu.doAction("Close");
                } else {
                    RSComponent component1 = interfaces.getComponent(109, 14);
                    if (component1.isValid()) {
                        mouse.click(component1.getCenter(), true);
                        long time = System.currentTimeMillis();
                        while (interfaces.getComponent(109, 14).isValid()) {
                            sleep(random(100, 200));
                            if (System.currentTimeMillis() - time >= 1500) {
                                return false;
                            }
                        }
                    } else {
                        sleep(random(200, 300));
                        return interfaces.getComponent(109, 14).isValid();
                    }
                }
                sleep(random(200, 300));
            } catch (Exception e) {
                return false;
            }
            return interfaces.getComponent(109, 14).isValid();
        }

        public boolean openBank() {
            try {
                sleep(random(100, 300));
                if (!locations.openBank()) {
                    return false;
                }
                sleep(random(100, 300));
            } catch (Exception e) {
                return false;
            }
            return true;
        }

        public boolean withdraw() {
            try {
                sleep(random(100, 300));
                if (!locations.withdraw()) {
                    return false;
                }
                sleep(random(100, 300));
            } catch (Exception e) {
                return false;
            }
            return true;
        }

        public boolean deposit() {
            try {
                sleep(random(100, 300));
                if (!locations.deposit()) {
                    return false;
                }
                sleep(random(100, 300));
            } catch (Exception e) {
                return false;
            }
            return true;
        }

        public boolean clickContinue() {
            try {
                sleep(random(100, 300));
                if (!interfaces.clickContinue()) {
                    return false;
                }
                sleep(random(100, 300));
            } catch (Exception e) {
                return false;
            }
            return true;
        }

        public boolean walkBank() {
            try {
                sleep(random(100, 300));
                if (!locations.walkToBank()) {
                    return false;
                }
                sleep(random(100, 300));
            } catch (Exception e) {
                return false;
            }
            return true;
        }

        public boolean walkWater() {
            try {
                sleep(random(100, 300));
                if (!locations.walkToWater()) {
                    return false;
                }
            } catch (Exception e) {
                return false;
            }
            sleep(random(100, 300));
            return true;
        }

        public boolean fillItems() {
            try {
                sleep(random(100, 300));
                if (!locations.clickWater()) {
                    return false;
                }
                sleep(random(100, 300));
            } catch (Exception e) {
                return false;
            }
            return true;
        }

        public void stop() {
            running = false;
            stopScript();
        }
    }

    //Copied from RSBot 2.27
    private Point[] getAllModelPoints(RSModel model) {
        if (model == null) {
            return null;
        }
        Polygon[] polygonPlural = model.getTriangles();
        Point[] points = new Point[polygonPlural.length * 3];
        int counter = 0;
        for (Polygon currentPoly : polygonPlural) {
            for (int i = 0; i < 3; i++) {
                points[counter++] = new Point(currentPoly.xpoints[i], currentPoly.ypoints[i]);
            }
        }
        return points;
    }

    //Again copied from RSBot 2.27
    private Point getMiddlePoint(RSModel model) {
        try {
            if (model == null) {
                return null;
            }
            int x = 0, y = 0, total = 0;
            for (Polygon polygon : model.getTriangles()) {
                for (int i = 0; i < polygon.npoints; i++) {
                    x += polygon.xpoints[i];
                    y += polygon.ypoints[i];
                    total++;
                }
            }
            Point central = new Point(x / total, y / total);
            Point curCentral = new Point(-1, -1);
            double dist = 20000;
            for (Polygon poly : model.getTriangles()) {
                for (int i = 0; i < poly.npoints; i++) {
                    Point p = new Point(poly.xpoints[i], poly.ypoints[i]);
                    if (!calc.pointOnScreen(p)) {
                        continue;
                    }
                    double dist2 = calcBetweenPoints(central, p);
                    if (curCentral == null || dist2 < dist) {
                        curCentral = p;
                        dist = dist2;
                    }
                }
            }
            return curCentral;
        } catch (Exception ignored) {
        }
        return new Point(-1, -1);
    }

    //Once again.
    private double calcBetweenPoints(Point p1, Point p2) {
        if (p1 != null && p2 != null) {
            return Math.sqrt(((p1.x - p2.x) * (p1.x - p2.x)) + ((p1.y - p2.y) * (p1.y - p2.y)));
        }
        return -1;
    }

    //Copied from RSBotAB, because it was private
    private void moveMouseRandomly(int maxDistance) {
        Point p = mouse.getLocation();
        int x = random(Math.max(0, p.x - maxDistance), Math.min(p.x + maxDistance, game.getWidth()));
        int y = random(Math.max(0, p.y - maxDistance), Math.min(p.y + maxDistance, game.getHeight()));
        mouse.move(x, y);
    }

    private boolean doActionObject(RSObject object, String action) {
        if (object == null) {
            return false;
        }
        RSModel model = object.getModel();
        if (model != null) {
            Point p = getMiddlePoint(model);
            if (p.x == -1 || p.y == -1) {
                p = model.getPoint();
            }
            if (p.x == -1 || p.y == -1) {
                p = getMiddlePoint(model);
            }
            if (p.x == -1 || p.y == -1) {
                Point[] points = getAllModelPoints(model);
                int pointChooser = random(0, points.length - 1);
                Point temp = points[pointChooser];
                if (temp.x != -1 && temp.y != -1) {
                    p = temp;
                }
            }
            mouse.move(p);
            sleep(random(5, 40));
            if (menu.contains(action)) {
                return menu.doAction(action);
            }
        } else {
            if (doHoverObj(object)) {
                if (menu.contains(action)) {
                    return menu.doAction(action);
                }
            }
        }
        return tiles.doAction(object.getLocation(), 0.5, 0.5, 0, action);
    }

    //My alternative to walkTileMM
    private boolean walkTileMap(RSTile t, int i) {
        if (t == null || i == -1) {
            return false;
        }
        RSTile clicked = walking.getDestination();
        if (clicked != null) {
            if (t.equals(clicked)) {
                return true;
            }
            if (calc.distanceBetween(t, clicked) <= i) {
                return true;
            }
        }
        if (calc.distanceTo(t) <= i) {
            return true;
        }
        Point point = calc.tileToMinimap(t);
        if (point.x == -1 || point.y == -1) {
            return false;
        }
        mouse.move(point.x + random(-9, 9), point.y + random(-9, 9), random(0, 12));
        Point point2 = calc.tileToMinimap(t);
        if (point2.x != -1 && point2.y != -1) {
            mouse.move(point.x + random(-3, 1), point.y + random(-3, 1));
        }
        sleep(random(random(0, 3), random(6, 10)));
        Point point3 = calc.tileToMinimap(t);
        if (point3.x != -1 && point3.y != -1) {
            mouse.click(point3, true);
            return true;
        } else if (point2.x != -1 && point2.y != -1) {
            mouse.click(point2, true);
            return true;
        } else if (point.x != -1 && point.y != -1) {
            mouse.click(point, true);
            return true;
        }
        return false;
    }

    //An edited traverse().
    private boolean doWalk(RSPath path, EnumSet<TraversalOption> walkOptions) {
        boolean bank = false;
        if (locations.bankArea().contains(path.getEnd())) {
            bank = true;
        }
        mouse.setSpeed(random(mouseLo, mouseHi));
        int random1 = random(1, 8);
        RSTile next = path.getNext();
        if (next == null) {
            return false;
        }
        if (random1 == 1) {
            mouse.moveRandomly(random(7, 14));
        } else if (random1 == 4) {
            mouse.moveRandomly(random(16, 20));
        } else if (random1 == 8) {
            mouse.moveRandomly(random(4, 12));
        }
        if (next.equals(path.getEnd())) {
            if (calc.distanceTo(next) <= 3 || (end && getMyPlayer().isMoving())) {
                if (bank && getMyPlayer().getLocation().getX() == 3273 && !getMyPlayer().isMoving()) {
                } else {
                    return false;
                }
            }
            end = true;
        } else {
            end = false;
        }
        if (walkOptions.contains(TraversalOption.HANDLE_RUN) && !walking.isRunEnabled() && walking.getEnergy() >= random(40, 60)) {
            walking.setRun(true);
            sleep(random(200, 300));
        }
        if (walkOptions.contains(TraversalOption.SPACE_ACTIONS)) {
            RSTile clickedTile = walking.getDestination();
            if (clickedTile != null && getMyPlayer().isMoving() && calc.distanceTo(clickedTile) > random(5, 7) && calc.distanceTo(next) > 3 && !next.equals(path.getEnd())) {
                if (bank && getMyPlayer().getLocation().getX() == 3273 && !getMyPlayer().isMoving()) {
                }
                sleep(random(220, 260));
                return true;
            }
        }
        if (!isPaused() && isActive() && isRunning()) {
            return walkTileMap(next, 2); //I use the int simply as a failsafe; in Al Kharid there is one spot that the player isn't in bankArea but the distance to the end tile is 3.
        } else {
            return false;
        }
    }

    private abstract class locations {

        public abstract boolean walkToBank();

        public abstract boolean walkToWater();

        public abstract int[] BankerID();

        public abstract int[] bankBoothID();

        public abstract int[] waterID();

        public abstract String waterName();

        public abstract RSArea fullArea();

        public abstract RSArea bankArea();

        public abstract RSArea waterArea();

        public abstract boolean deposit();

        public abstract boolean withdraw();

        public abstract boolean clickWater();

        public abstract RSTile fountainTile();

        public abstract RSTile bankTile();

        public abstract boolean openBank();

        public abstract boolean closeBank();
    }

    private class alKharid extends locations {

        private RSTile onWaterTile = new RSTile(3293, 3173);
        private RSTile bankTile = new RSTile(3270, 3168), waterTile = new RSTile(3292, 3175);
        private RSArea bankArea = new RSArea(new RSTile[]{new RSTile(3273, 3175), new RSTile(3273, 3167), new RSTile(3273, 3160), new RSTile(3267, 3160), new RSTile(3267, 3174)});
        private RSArea waterArea = new RSArea(new RSTile[]{new RSTile(3288, 3176), new RSTile(3288, 3168), new RSTile(3297, 3169), new RSTile(3297, 3177), new RSTile(3294, 3180), new RSTile(3290, 3180)});
        private RSArea fullArea = new RSArea(new RSTile[]{new RSTile(3282, 3165), new RSTile(3302, 3166), new RSTile(3302, 3176), new RSTile(3301, 3177), new RSTile(3300, 3178), new RSTile(3297, 3178), new RSTile(3294, 3180), new RSTile(3285, 3186), new RSTile(3281, 3186), new RSTile(3269, 3181), new RSTile(3264, 3173), new RSTile(3264, 3161), new RSTile(3265, 3160), new RSTile(3273, 3160), new RSTile(3279, 3158)});
        private int[] Banker = {497, 496};
        private int[] BankBooth = {35467};
        private int[] water = {35469};
        private String Water = "Carved fountain";

        @Override
        public boolean walkToBank() {
            end = false;
            canAntiBan = false;
            RSTile walkTile = this.bankTile();
            RSPath path = walking.getPath(walkTile);
            long timeout = 10000;
            if (path != null) {
                long walkTimer = System.currentTimeMillis();
                while ((doWalk(path, EnumSet.of(TraversalOption.HANDLE_RUN, TraversalOption.SPACE_ACTIONS)) || !locations.bankArea().contains(getMyPlayer().getLocation())) && !isPaused() && isActive() && isRunning()) {
                    sleep(random(200, 300));
                    if (walking.isRunEnabled()) {
                        timeout = 11000;
                    } else {
                        timeout = 17000;
                    }
                    if (System.currentTimeMillis() - walkTimer >= timeout) {
                        canAntiBan = true;
                        break;
                    }
                    sleep(random(100, 150));
                }
                sleep(random(80, 130));
                camera.turnToTile(walkTile);
            } else {
                canAntiBan = true;
                return false;
            }
            canAntiBan = true;
            return locations.bankArea().contains(getMyPlayer().getLocation());
        }

        @Override
        public boolean walkToWater() {
            end = false;
            canAntiBan = false;
            RSTile walkTile = this.fountainTile();
            RSPath path = walking.getPath(walkTile);
            long timeout = 10000;
            if (path != null) {
                long walkTimer = System.currentTimeMillis();
                while ((doWalk(path, EnumSet.of(TraversalOption.HANDLE_RUN, TraversalOption.SPACE_ACTIONS)) || !locations.waterArea().contains(getMyPlayer().getLocation())) && !isPaused() && isActive() && isRunning()) {
                    sleep(random(200, 300));
                    if (walking.isRunEnabled()) {
                        timeout = 11000;
                    } else {
                        timeout = 17000;
                    }
                    if (System.currentTimeMillis() - walkTimer >= timeout) {
                        canAntiBan = true;
                        break;
                    }
                    sleep(random(100, 150));
                }
                sleep(random(80, 130));
                camera.turnToTile(walkTile);
            } else {
                canAntiBan = true;
                return false;
            }
            canAntiBan = true;
            if (camera.getPitch() <= 95) {
                camera.setPitch(true);
            }
            return locations.waterArea().contains(getMyPlayer().getLocation());
        }

        @Override
        public int[] BankerID() {
            return Banker;
        }

        @Override
        public int[] bankBoothID() {
            return BankBooth;
        }

        @Override
        public int[] waterID() {
            return water;
        }

        @Override
        public String waterName() {
            return Water;
        }

        @Override
        public RSArea fullArea() {
            return fullArea;
        }

        @Override
        public RSArea bankArea() {
            return bankArea;
        }

        @Override
        public RSArea waterArea() {
            return waterArea;
        }

        @Override
        public boolean deposit() {
            canAntiBan = false;
            try {
                int count = inventory.getCount();
                bank.depositAll();
                long Timer = System.currentTimeMillis();
                while (inventory.getCount() == count) {
                    sleep(random(100, 300));
                    if (System.currentTimeMillis() - Timer >= 1000) {
                        break;
                    }
                }
            } catch (Exception e) {
            }
            canAntiBan = true;
            sleep(random(300, 400));
            return !inventory.contains(item.fullID());
        }

        @Override
        public boolean withdraw() {
            canAntiBan = false;
            bank.withdraw(item.emptyID(), 0);
            canAntiBan = true;
            sleep(random(500, 600));
            return inventory.contains(item.emptyID());
        }

        @Override
        public boolean clickWater() {
            sleep(random(300, 400));
            long Timer = System.currentTimeMillis();
            RSItem emptyItem = getRandomEmptyItem();
            if (emptyItem == null) {
                return false;
            }
            canAntiBan = false;
            boolean moveCamera = camera.getPitch() <= 90;
            if (random(1, 2) == 2 && moveCamera) {
                if (random(1, 2) == 2) {
                    int random = random(1, 3);
                    if (random == 1) {
                        camera.setPitch(true);
                    } else if (random == 2) {
                        camera.setPitch(false);
                    }
                    camera.setCompass('s');
                } else {
                    if (random(1, 2) == 1) {
                        camera.setPitch(true);
                    }
                    camera.setCompass('n');
                    if (camera.getPitch() <= 95) {
                        camera.setPitch(true);
                    }
                }
            }
            while (!inventory.isItemSelected()) {
                emptyItem.doAction("Use");
                sleep(random(400, 500));
                if (System.currentTimeMillis() - Timer >= 1500) {
                    break;
                }
            }
            String itemName = inventory.getSelectedItemName();
            if (itemName != null) {
                if (moveCamera && camera.getPitch() <= 95) {
                    if (random(1, 2) == 1) {
                        int random = random(1, 4);
                        if (random == 1) {
                            camera.setPitch(false);
                        } else if (random == 2) {
                            camera.setPitch(true);
                        }
                        camera.setCompass('s');
                        if (random == 3) {
                            camera.setPitch(false);
                        }
                    } else {
                        int random = random(1, 3);
                        if (random == 1) {
                            camera.setPitch(true);
                        } else if (random == 2) {
                            int random2 = random(1, 2);
                            if (random2 == 1) {
                                camera.setPitch(true);
                            }
                            camera.setCompass('n');
                            if (random2 == 2) {
                                camera.setPitch(false);
                            }
                        } else if (random == 3) {
                            int random2 = random(1, 2);
                            int random3 = random(1, 2);
                            if (random2 == 1) {
                                if (random3 == 1) {
                                    camera.setPitch(true);
                                }
                                camera.setCompass('e');
                                if (random3 == 2) {
                                    camera.setPitch(true);
                                }
                            } else {
                                if (random3 == 1) {
                                    camera.setPitch(true);
                                }
                                camera.setCompass('e');
                                if (random3 == 2) {
                                    camera.setPitch(true);
                                }
                            }
                        }
                    }
                }
                RSObject waterObj = objects.getNearest(water);
                if (waterObj == null) {
                    Point p = calc.tileToScreen(onWaterTile, 0.5, 0.5, 0);
                    mouse.move(p);
                    RSObject temp = objects.getNearest(water);
                    if (temp == null) {
                        temp = objects.getTopAt(onWaterTile);
                    }
                    if (temp != null) {
                        waterObj = temp;
                    } else {
                        canAntiBan = true;
                        return false;
                    }
                }
                if (waterObj != null && !waterObj.isOnScreen()) {
                    camera.turnToObject(waterObj);
                }
                sleep(random(200, 300));
                if (!doActionObject(waterObj, "Use " + itemName + " -> Carved fountain")) {
                    if (!waterObj.doAction("Use " + itemName + " -> Carved fountain")) {
                        if (!doHoverObj(waterObj)) {
                            RSModel model = waterObj.getModel();
                            if (model != null) {
                                mouse.move(model.getPoint());
                            } else {
                                if (!doHoverObj(waterObj)) {
                                    mouse.move(calc.tileToScreen(onWaterTile, 0.5, 0.5, 0));
                                }
                            }
                        }
                        sleep(random(20, 50));
                        menu.doAction("Use " + itemName + " -> Carved fountain");
                    }
                }
            } else if (inventory.isItemSelected()) {
                RSObject waterObj = objects.getNearest(water);
                if (water != null) {
                    RSModel model = waterObj.getModel();
                    if (model != null) {
                        mouse.move(model.getPoint());
                    } else {
                        mouse.move(calc.tileToScreen(onWaterTile, 0.5, 0.5, 0));
                    }
                    if (!menu.doAction("Use " + inventory.getSelectedItemName() + " -> Carved fountain")) {
                        waterObj.doAction("Use " + inventory.getSelectedItemName() + " -> Carved fountain");
                    }
                }
            } else if (!inventory.isItemSelected()) {
                getRandomEmptyItem().doClick(true);
            }
            canAntiBan = true;
            sleep(random(200, 300));
            return isFilling();
        }

        @Override
        public RSTile fountainTile() {
            RSTile returnTile = waterTile.randomize(random(0, 2), random(0, 2));
            if (waterArea.contains(returnTile) && walking.getPath(returnTile).isValid()) {
                return returnTile;
            } else {
                return waterTile;
            }
        }

        @Override
        public RSTile bankTile() {
            RSTile returnTile = bankTile.randomize(random(0, 2), random(0, 2));
            if (bankArea.contains(returnTile) && walking.getPath(returnTile).isValid()) {
                return returnTile;
            } else {
                return bankTile;
            }
        }

        @Override
        public boolean openBank() {
            canAntiBan = false;
            sleep(random(100, 350));
            RSNPC banknpc = getNearestNPC(Banker);
            if (banknpc != null) {
                RSTile t = banknpc.getLocation();
                if (!calc.tileOnScreen(t)) {
                    camera.turnToTile(t);
                }
            } else {
                RSObject bankobj = objects.getNearest(BankBooth);
                if (bankobj != null) {
                    RSTile t = bankobj.getLocation();
                    if (!calc.tileOnScreen(t)) {
                        camera.turnToTile(t);
                    }
                }
            }
            if (!bank.open()) {
                if (random(1, 6) >= 2) {
                    RSObject bank = objects.getNearest(BankBooth);
                    if (bank != null) {
                        if (!bank.isOnScreen()) {
                            camera.turnToObject(bank);
                        }
                        if (random(1, 2) == 2) {
                            mouse.move(bank.getModel().getPoint());
                        } else if (random(1, 5) == 5) {
                            doHoverObj(bank);
                        }
                        if (!bank.doAction("Use-quickly")) {
                            camera.turnToObject(bank);
                            if (!doHoverObj(bank)) {
                                return false;
                            }
                            menu.doAction("Use-quickly");
                        }
                        if (random(1, 3) >= 2) {
                            mouse.moveRandomly(random(40, 60));
                        }
                        long Timer = System.currentTimeMillis();
                        while (interfaces.getComponent(Bank.INTERFACE_BANK).isValid()) {
                            sleep(random(80, 120));
                            if (System.currentTimeMillis() - Timer >= 1500) {
                                break;
                            }
                        }
                        sleep(random(200, 300));
                    } else {
                        canAntiBan = true;
                        return false;
                    }
                } else {
                    RSNPC banker = getNearestNPC(Banker);
                    if (banker != null) {
                        if (random(1, 5) == 5) {
                            mouse.move(banker.getModel().getPoint());
                        } else if (random(1, 2) == 2) {
                            Point p = calc.tileToScreen(banker.getLocation(), 0.5, 0.5, 0);
                            Point temp = new Point(p.x, (int) (p.y + (banker.getHeight() / random(1.8, 2.2)) + random(-5, 5)));
                            Point temp2 = getMiddlePoint(banker.getModel());
                            boolean contains = false;
                            boolean contains2 = false;
                            Point[] points = getAllModelPoints(banker.getModel());
                            for (int i = 0; i < points.length; i++) {
                                Point newPoint = points[i];
                                if (newPoint.equals(temp)) {
                                    contains = true;
                                    break;
                                }
                            }
                            for (int i = 0; i < points.length; i++) {
                                Point newPoint = points[i];
                                if (newPoint.equals(temp2)) {
                                    contains2 = true;
                                    break;
                                }
                            }
                            if (temp.x != -1 && temp.y != -1 && contains) {
                                p = temp;
                            }
                            if (temp2.x != -1 && temp2.y != -1 && contains2) {
                                p = temp2;
                            }
                            mouse.move(p);
                        }
                        if (!banker.doAction("Bank Banker")) {
                            camera.turnToCharacter(banker);
                        }
                        if (random(1, 3) >= 2) {
                            mouse.moveRandomly(random(40, 60));
                        }
                        long Timer = System.currentTimeMillis();
                        while (interfaces.getComponent(Bank.INTERFACE_BANK).isValid()) {
                            sleep(random(80, 120));
                            if (System.currentTimeMillis() - Timer >= 1500) {
                                break;
                            }
                        }
                        sleep(random(200, 300));
                    } else {
                        canAntiBan = true;
                        return false;
                    }
                }
            }
            canAntiBan = true;
            sleep(random(200, 300));
            long Time = System.currentTimeMillis();
            while (!bank.isOpen()) {
                sleep(random(100, 150));
                if (System.currentTimeMillis() - Time >= 1000) {
                    break;
                }
            }
            sleep(random(100, 150));
            return bank.isOpen();
        }

        @Override
        public boolean closeBank() {
            canAntiBan = false;
            if (!bank.close()) {
                mouse.move(interfaces.getComponent(Bank.INTERFACE_BANK_BUTTON_CLOSE).getCenter());
                canAntiBan = true;
                return menu.doAction("Close");
            } else {
                canAntiBan = true;
                return true;
            }
        }
    }

    private class FaladorWest extends locations {

        private RSTile onWaterTile = new RSTile(2948, 3383);
        private RSTile bankTile = new RSTile(2947, 3368), waterTile = new RSTile(2949, 3382);
        private RSArea bankArea = new RSArea(new RSTile[]{new RSTile(2948, 3374), new RSTile(2948, 3370), new RSTile(2950, 3370), new RSTile(2950, 3365), new RSTile(2949, 3365), new RSTile(2949, 3363), new RSTile(2945, 3363), new RSTile(2945, 3365), new RSTile(2944, 3365), new RSTile(2944, 3367), new RSTile(2942, 3367), new RSTile(2942, 3374)});
        private RSArea waterArea = new RSArea(new RSTile[]{new RSTile(2945, 3381), new RSTile(2945, 3385), new RSTile(2953, 3385), new RSTile(2953, 3380)});
        private RSArea fullArea = new RSArea(new RSTile[]{new RSTile(2943, 3358), new RSTile(2951, 3358), new RSTile(2958, 3384), new RSTile(2952, 3390), new RSTile(2945, 3388), new RSTile(2942, 3386), new RSTile(2942, 3378), new RSTile(2937, 3368)});
        private int[] Banker = {6200};
        private int[] BankBooth = {11758};
        private int[] water = {0};
        private String Water = "Waterpump";

        @Override
        public boolean walkToBank() {
            canAntiBan = false;
            RSTile walkTile = this.bankTile();
            RSPath path = walking.getPath(walkTile);
            if (walking.getEnergy() >= random(40, 60) && !walking.isRunEnabled()) {
                walking.setRun(true);
                sleep(random(200, 300));
            }
            if (path != null) {
                if (!path.traverse()) {
                    canAntiBan = true;
                    return false;
                }
            } else {
                canAntiBan = true;
                return false;
            }
            canAntiBan = true;
            return true;
        }

        @Override
        public boolean walkToWater() {
            canAntiBan = false;
            long Timer = System.currentTimeMillis();
            RSTile walkTile = this.fountainTile();
            RSPath path = walking.getPath(walkTile);
            if (path != null) {
                if (!path.traverse()) {
                    canAntiBan = true;
                    return false;
                }
            } else {
                canAntiBan = true;
                return false;
            }
            canAntiBan = true;
            if (camera.getPitch() <= 90) {
                camera.setPitch(true);
            }
            return true;
        }

        @Override
        public int[] BankerID() {
            return Banker;
        }

        @Override
        public int[] waterID() {
            return water;
        }

        @Override
        public int[] bankBoothID() {
            return BankBooth;
        }

        @Override
        public RSArea fullArea() {
            return fullArea;
        }

        @Override
        public RSArea bankArea() {
            return bankArea;
        }

        @Override
        public RSArea waterArea() {
            return waterArea;
        }

        private RSObject getNearestWaterpump() {
            RSObject object1 = null;
            RSObject object2 = null;
            RSObject finalObject = null;
            try {
                object1 = objects.getNearest(new org.rsbot.script.util.Filter<RSObject>() {

                    public boolean accept(RSObject water) {
                        if (locations.waterArea().contains(water.getLocation()) || water.getDef().getName().toLowerCase().contains("pump")) {
                            return true;
                        } else {
                            return false;
                        }
                    }
                });
            } catch (Exception e) {
            }
            if (object1 == null) {
                try {
                    object2 = objects.getNearest(new org.rsbot.script.util.Filter<RSObject>() {

                        public boolean accept(RSObject water) {
                            if (water.getLocation().equals(onWaterTile) || objects.getTopAt(onWaterTile).equals(water)) {
                                return true;
                            } else {
                                return false;
                            }
                        }
                    });
                } catch (Exception e) {
                }
            }
            if (object1 != null) {
                finalObject = object1;
            } else if (object2 != null) {
                finalObject = object2;
            } else {
                finalObject = objects.getNearest("Waterpump");
            }
            return finalObject;
        }

        public boolean clickWater() {
            sleep(random(300, 400));
            long Timer = System.currentTimeMillis();
            RSItem emptyItem = getRandomEmptyItem();
            if (emptyItem == null) {
                return false;
            }
            canAntiBan = false;
            boolean moveCamera = camera.getPitch() <= 90;
            int random = random(1, 6);
            if (moveCamera) {
                if (random == 1) {
                    camera.setCompass('w');
                } else if (random == 2) {
                    int random2 = random(1, 2);
                    if (camera.getPitch() <= 99) {
                        if (random2 == 1) {
                            camera.setPitch(true);
                        }
                    }
                    camera.setCompass('e');
                    if (camera.getPitch() <= 99) {
                        if (random2 == 2) {
                            camera.setPitch(true);
                        }
                    }
                } else if (random == 3) {
                    camera.setPitch(true);
                }
            }
            while (!inventory.isItemSelected()) {
                emptyItem.doAction("Use");
                sleep(random(400, 500));
                if (System.currentTimeMillis() - Timer >= 1500) {
                    break;
                }
            }
            String itemName = inventory.getSelectedItemName();
            if (itemName != null) {
                if (moveCamera) {
                    if (random == 4) {
                        camera.setCompass('w');
                    } else if (random == 5) {
                        int random2 = random(1, 2);
                        if (camera.getPitch() <= 99) {
                            if (random2 == 1) {
                                camera.setPitch(true);
                            }
                        }
                        camera.setCompass('e');
                        if (camera.getPitch() <= 99) {
                            if (random2 == 2) {
                                camera.setPitch(true);
                            }
                        }
                    } else if (random == 6) {
                        camera.setPitch(true);
                    }
                }
                RSObject waterObj = getNearestWaterpump();
                if (waterObj == null) {
                    Point p = calc.tileToScreen(onWaterTile, 0.5, 0.5, 0);
                    mouse.move(p);
                    RSObject temp = getNearestWaterpump();
                    if (temp == null) {
                        temp = objects.getTopAt(onWaterTile);
                    }
                    if (temp != null) {
                        waterObj = temp;
                    } else {
                        canAntiBan = true;
                        return false;
                    }
                }
                if (waterObj != null && !waterObj.isOnScreen()) {
                    camera.turnToObject(waterObj);
                }
                sleep(random(200, 300));
                if (!doActionObject(waterObj, "Use " + itemName + " -> Waterpump")) {
                    if (!waterObj.doAction("Use " + itemName + " -> Waterpump")) {
                        if (!doHoverObj(waterObj)) {
                            RSModel model = waterObj.getModel();
                            if (model != null) {
                                mouse.move(model.getPoint());
                            } else {
                                if (!doHoverObj(waterObj)) {
                                    mouse.move(calc.tileToScreen(waterObj.getLocation(), 0.5, 0.5, 0));
                                }
                            }
                        }
                        sleep(random(20, 50));
                        menu.doAction("Use " + itemName + " -> Waterpump");
                    }
                }
            } else if (inventory.isItemSelected()) {
                RSObject water = getNearestWaterpump();
                if (water != null) {
                    if (!doHoverObj(water)) {
                        if (water.getModel() != null) {
                            mouse.move(water.getModel().getPoint());
                        } else {
                            mouse.move(calc.tileToScreen(water.getLocation(), 0.5, 0.5, 0));
                        }
                    }
                    if (!menu.doAction("Use " + inventory.getSelectedItemName() + " -> Waterpump")) {
                        water.doAction("Use " + inventory.getSelectedItemName() + " -> Waterpump");
                    }
                }
            } else {
                if (!inventory.isItemSelected()) {
                    getEmptyItem().doClick(true);
                }
            }
            canAntiBan = true;
            sleep(random(200, 300));
            return isFilling();
        }

        @Override
        public RSTile fountainTile() {
            RSTile returnTile = waterTile.randomize(random(0, 2), random(0, 2));
            if (waterArea.contains(returnTile) && walking.getPath(returnTile).isValid()) {
                return returnTile;
            } else {
                return waterTile;
            }
        }

        @Override
        public RSTile bankTile() {
            RSTile returnTile = bankTile.randomize(random(0, 2), random(0, 2));
            if (bankArea.contains(returnTile)) {
                return returnTile;
            } else {
                return bankTile;
            }
        }

        @Override
        public boolean openBank() {
            canAntiBan = false;
            sleep(random(100, 350));
            if (random(1, 6) >= 2) {
                RSObject bank = objects.getNearest(BankBooth);
                if (bank != null) {
                    if (random(1, 2) == 2) {
                        mouse.move(bank.getModel().getPoint());
                    } else if (random(1, 5) == 5) {
                        doHoverObj(bank);
                    }
                    if (!bank.doAction("Use-quickly")) {
                        camera.turnToObject(bank);
                    }
                    if (random(1, 3) >= 2) {
                        mouse.moveRandomly(random(40, 60));
                    }
                    long Timer = System.currentTimeMillis();
                    while (interfaces.getComponent(Bank.INTERFACE_BANK).isValid()) {
                        sleep(random(80, 120));
                        if (System.currentTimeMillis() - Timer >= 1500) {
                            break;
                        }
                    }
                    sleep(random(200, 300));
                } else {
                    canAntiBan = true;
                    return false;
                }
            } else {
                RSNPC banker = getNearestNPC(Banker);
                if (banker != null) {
                    if (random(1, 2) == 2) {
                        mouse.move(banker.getModel().getPoint());
                    } else if (random(1, 5) == 5) {
                        Point p = calc.tileToScreen(banker.getLocation(), 0.5, 0.5, 0);
                        Point temp = new Point(p.x, (int) (p.y + (banker.getHeight() / random(1.8, 2.2)) + random(-5, 5)));
                        Point temp2 = getMiddlePoint(banker.getModel());
                        boolean contains = false;
                        boolean contains2 = false;
                        Point[] points = getAllModelPoints(banker.getModel());
                        for (int i = 0; i < points.length; i++) {
                            Point newPoint = points[i];
                            if (newPoint.equals(temp)) {
                                contains = true;
                                break;
                            }
                        }
                        for (int i = 0; i < points.length; i++) {
                            Point newPoint = points[i];
                            if (newPoint.equals(temp2)) {
                                contains2 = true;
                                break;
                            }
                        }
                        if (temp.x != -1 && temp.y != -1 && contains) {
                            p = temp;
                        }
                        if (temp2.x != -1 && temp2.y != -1 && contains2) {
                            p = temp2;
                        }
                        mouse.move(p);
                    }
                    if (!banker.doAction("Bank Banker")) {
                        camera.turnToCharacter(banker);
                    }
                    if (random(1, 3) >= 2) {
                        mouse.moveRandomly(random(40, 60));
                    }
                    long Timer = System.currentTimeMillis();
                    while (interfaces.getComponent(Bank.INTERFACE_BANK).isValid()) {
                        sleep(random(80, 120));
                        if (System.currentTimeMillis() - Timer >= 1500) {
                            break;
                        }
                    }
                    sleep(random(200, 300));
                } else {
                    canAntiBan = true;
                    return false;
                }
            }
            canAntiBan = true;
            sleep(random(200, 300));
            long Time = System.currentTimeMillis();
            while (!bank.isOpen()) {
                sleep(random(100, 150));
                if (System.currentTimeMillis() - Time >= 1000) {
                    break;
                }
            }
            sleep(random(100, 150));
            return bank.isOpen();
        }

        @Override
        public boolean closeBank() {
            canAntiBan = false;
            if (!bank.close()) {
                mouse.move(interfaces.getComponent(Bank.INTERFACE_BANK_BUTTON_CLOSE).getCenter());
                canAntiBan = true;
                return menu.doAction("Close");
            } else {
                canAntiBan = true;
                return true;
            }
        }

        @Override
        public boolean deposit() {
            canAntiBan = false;
            try {
                int count = inventory.getCount();
                bank.depositAll();
                long Timer = System.currentTimeMillis();
                while (inventory.getCount() == count) {
                    sleep(random(100, 300));
                    if (System.currentTimeMillis() - Timer >= 1000) {
                        break;
                    }
                }
            } catch (Exception e) {
            }
            canAntiBan = true;
            sleep(random(300, 400));
            return !inventory.contains(item.fullID());
        }

        @Override
        public boolean withdraw() {
            canAntiBan = false;
            bank.withdraw(item.emptyID(), 0);
            sleep(random(500, 600));
            canAntiBan = true;
            return inventory.contains(item.emptyID());
        }

        @Override
        public String waterName() {
            return Water;
        }
    }

    private RSItem getRandomEmptyItem() {
        RSItem[] items = inventory.getItems(item.emptyID());
        RSItem emptyItem = null;
        int randomNum = random(0, items.length - 1);
        emptyItem = items[randomNum];
        if (emptyItem == null) {
            emptyItem = inventory.getItem(item.emptyID());
        }
        return emptyItem;
    }

    private RSItem getEmptyItem() {
        RSItem[] vials = inventory.getItems(item.emptyID());
        RSItem emptyVial = null;
        int randomNumber = random(0, vials.length);
        for (int i = 0; i <= randomNumber; i++) {
            emptyVial = vials[i];
        }
        if (emptyVial == null) {
            emptyVial = inventory.getItem(item.emptyID());
        }
        return emptyVial;
    }

    private RSNPC getNearestNPC(final int[] IDs) {
        RSNPC[] allWithID = null;
        try {
            allWithID = npcs.getAll(new org.rsbot.script.util.Filter<RSNPC>() {

                public boolean accept(RSNPC n) {
                    for (int checkID : IDs) {
                        if (n.getID() == checkID) {
                            return true;
                        }
                    }
                    return false;
                }
            });
        } catch (Exception e) {
        }
        if (allWithID == null) {
            return null;
        }
        RSNPC closest = null;
        int distance = 100;
        for (RSNPC npc : allWithID) {
            if (calc.distanceTo(npc.getLocation()) < distance) {
                closest = npc;
            }
        }
        if (closest == null) {
            closest = npcs.getNearest(IDs);
        }
        return closest;
    }

    private boolean doHoverObj(final RSObject obj) {
        String name = "None";
        if (obj != null) {
            RSObjectDef def = obj.getDef();
            if (def == null) {
                def = obj.getDef();
            }
            if (def == null) {
                def = obj.getDef();
            }
            if (def != null) {
                name = def.getName();
                RSModel m = obj.getModel();
                if (m != null) {
                    Point p = m.getPoint();
                    mouse.move(p);
                } else {
                    mouse.move(calc.tileToScreen(obj.getLocation(), 0.5, 0.5, 0));
                }
                sleep(random(30, 60));
                return menu.contains(name);
            } else {
                RSModel m = obj.getModel();
                if (m != null) {
                    Point p = m.getPoint();
                    mouse.move(p);
                } else {
                    mouse.move(calc.tileToScreen(obj.getLocation(), 0.5, 0.5, 0));
                }
                sleep(random(30, 60));
                return tiles.getTileUnderMouse().equals(obj.getLocation());
            }
        }
        return false;
    }

    private boolean doHoverNPC(final RSNPC npc) {
        if (npc != null) {
            String name = npc.getName();
            RSModel model = npc.getModel();
            if (model != null) {
                mouse.move(model.getPoint());
            } else {
                mouse.move(calc.tileToScreen(npc.getLocation(), 0.5, 0.5, 0));
            }
            sleep(random(30, 60));
            return menu.contains(name);
        }
        if (npc != null) {
            RSTile t = npc.getLocation();
            mouse.move(calc.tileToScreen(t));
            sleep(random(30, 60));
            RSTile t2 = tiles.getTileUnderMouse();
            return t.equals(t2);
        }
        return false;
    }

    private boolean isFilling() {
        if (getMyPlayer().getAnimation() == -1) {
            sleep(random(800, 1000));
            if (getMyPlayer().getAnimation() == -1) {
                sleep(random(400, 600));
                if (getMyPlayer().getAnimation() == -1) {
                    return false;
                }
            }
        }
        return true;
    }

    private boolean walk(RSTile destination, int distance) {
        if (calc.distanceTo(destination) > distance) {
            RSPath path = walking.getPath(destination);
            if (path != null) {
                if (last != null) {
                    if (getMyPlayer().isMoving()) {
                        while (calc.distanceTo(last) >= random(5, 9)) {
                            sleep(80, 120);
                            if (!getMyPlayer().isMoving()) {
                                sleep(200, 300);
                                if (!getMyPlayer().isMoving()) {
                                    break;
                                }
                            }
                        }
                    }
                }
                RSTile next = path.getNext();
                if (next != null) {
                    Point point = calc.tileToMinimap(next);
                    if (point != null) {
                        int pointX = point.x;
                        int pointY = point.y;
                        if (pointX == -1 || pointY == -1) {
                            long timer = System.currentTimeMillis();
                            while (!walking.isLocal(next)) {
                                sleep(80, 120);
                                point = calc.tileToMinimap(next);
                                if (System.currentTimeMillis() - timer >= 3000) {
                                    return false;
                                }
                            }
                        }
                        if (point == null || point.x == -1 || point.y == -1) {
                            last = next;
                            return false;
                        }
                        mouse.move(point, random(-10, 10), random(-10, 10));
                        mouse.click(point, true);
                        last = next;
                        if (last.equals(destination)
                                || next.equals(destination)
                                || calc.distanceBetween(destination, last) <= distance
                                || calc.distanceBetween(last, destination) <= distance) {
                            camera.turnToTile(destination);
                            return false;
                        }
                        return true;
                    }
                }
            }
        } else if (calc.distanceTo(destination) <= distance) {
            camera.turnToTile(destination);
            return false;
        }
        return false;
    }

    private class item {

        private final int full, empty;

        public item(final int empty, final int full) {
            this.empty = empty;
            this.full = full;
        }

        public int emptyID() {
            return empty;
        }

        public int fullID() {
            return full;
        }
    }

    private class GUI extends JFrame {

        private static final long serialVersionUID = 570716943631400833L;
        private final String[] type = new String[]{"Vials"};
        private final String[] locations = new String[]{"Falador West", "Al Kharid"};
        private final String[] mouseString = new String[]{"0", "1", "2", "3",
            "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16"};
        private boolean cancel = false;
        private JButton cancelButton = new JButton("Cancel");
        private JComboBox waterLocations = new JComboBox(locations);
        private JComboBox itemTypes = new JComboBox(type);
        private JComboBox mouseHi = new JComboBox(mouseString);
        private JComboBox mouseLo = new JComboBox(mouseString);
        private JButton startButton = new JButton("Start");
        private JLabel title = new JLabel(
                "<html><body><b><font size=\"5\">Aut0Filler</font></b></body></html>");

        public boolean isCancelled() {
            return cancel;
        }

        public String getItemType() {
            return (String) itemTypes.getSelectedItem();
        }

        public int getItemLocation() {
            return waterLocations.getSelectedIndex();
        }

        public int getMouseHi() {
            return mouseHi.getSelectedIndex();
        }

        public int getMouseLo() {
            return mouseLo.getSelectedIndex();
        }

        public GUI() {
            setLayout(new BorderLayout());
            add(new NorthPanel(), BorderLayout.NORTH);
            add(new CenterPanel(), BorderLayout.CENTER);
            add(new SouthPanel(), BorderLayout.SOUTH);
            pack();
        }

        class GUIActionListener implements ActionListener {

            public void actionPerformed(ActionEvent event) {
                if (event.getActionCommand().equals("Cancel")) {
                    cancel = true;
                    setVisible(false);
                } else if (event.getActionCommand().equals("Start")) {
                    setVisible(false);
                }
            }
        }

        class NorthPanel extends JPanel {

            private static final long serialVersionUID = -532956719518981384L;

            public NorthPanel() {
                setLayout(new GridLayout(1, 1));
                add(title);
            }
        }

        class CenterPanel extends JPanel {

            private static final long serialVersionUID = 7828700674189907012L;

            public CenterPanel() {
                mouseLo.setSelectedIndex(5);
                mouseHi.setSelectedIndex(10);
                setLayout(new GridLayout(0, 2));
                add(new JLabel("Fill Item:"));
                add(itemTypes);
                add(new JLabel("Location:"));
                add(waterLocations);
                add(new JLabel("Fastest Mouse Speed:"));
                add(mouseLo);
                add(new JLabel("Slowest Mouse Speed:"));
                add(mouseHi);
            }
        }

        class SouthPanel extends JPanel {

            private static final long serialVersionUID = -7538261008658025548L;

            public SouthPanel() {
                cancelButton.setActionCommand("Cancel");
                cancelButton.addActionListener(new GUIActionListener());
                startButton.setActionCommand("Start");
                startButton.addActionListener(new GUIActionListener());
                setLayout(new GridLayout(1, 2));
                add(cancelButton);
                add(startButton);
            }
        }
    }

    private class AntiBan implements Runnable {

        private void sleep(int t) {
            try {
                Thread.sleep(t);
            } catch (final Exception e) {
            }
        }

        public AntiBan() {
            new Thread(this).start();
            new Thread(this).start();
            failSafe failsafe = new failSafe();
        }

        public void run() {
            while (running) {
                final int rand = random(0, random(120, 130));
                if (canAntiBan && !isPaused() && isActive() && isRunning() && bank != null && !bank.isOpen()) {
                    if (!mouseChecker.movedRecently()) {
                        switch (rand) {
                            case 0: {
                                mouse.setSpeed(random(mouseLo, mouseHi));
                                break;
                            }
                            case 1: {
                                if (canAntiBan) {
                                    mouse.moveSlightly();
                                    mouse.moveSlightly();
                                }
                                break;
                            }
                            case 2: {
                                if (canAntiBan) {
                                    mouse.moveOffScreen();
                                    break;
                                }
                            }
                            case 3: {
                                if (canAntiBan) {
                                    mouse.moveSlightly();
                                    mouse.moveRandomly(random(20, 40), random(50, 60));
                                }
                                break;
                            }
                            case 4: {
                                if (canAntiBan) {
                                    mouse.move(random(175, 325), random(75, 225));
                                }
                                break;
                            }
                            case 5: {
                                if (canAntiBan) {
                                    mouse.moveSlightly();
                                    mouse.moveOffScreen();
                                }
                                break;
                            }
                        }
                    }
                    if (!cameraChecker.movedRecently()) {
                        switch (rand) {
                            case 6: {
                                camera.moveRandomly(random(800, 1200));
                                break;
                            }
                            case 7: {
                                camera.setPitch(true);
                                break;
                            }
                            case 8: {
                                camera.setPitch(false);
                                break;
                            }
                            case 9: {
                                camera.setAngle(random(5, 40));
                                sleep(random(200, 300));
                                break;
                            }
                            case 10: {
                                camera.setAngle(random(10, 50));
                                break;
                            }
                            case 11: {
                                camera.setPitch(random(40, 68));
                                break;
                            }
                            case 12: {
                                camera.moveRandomly(random(400, 800));
                                break;
                            }
                            case 13: {
                                camera.setAngle(random(10, 100));
                                break;
                            }
                            case 14: {
                                sleep(random(200, 300));
                                int randomInt = random(1, 4);
                                if (randomInt == 1) {
                                    camera.setCompass('n');
                                } else if (randomInt == 2) {
                                    camera.setCompass('s');
                                } else if (randomInt == 3) {
                                    camera.setCompass('w');
                                } else if (randomInt == 4) {
                                    camera.setCompass('e');
                                }
                                break;
                            }
                            case 15: {
                                camera.moveRandomly(random(200, 800));
                            }
                            break;
                            case 16: {
                                RSObject obj = null;
                                if (string) {
                                    obj = objects.getNearest(locations.waterName());
                                } else {
                                    obj = objects.getNearest(locations.waterID());
                                }
                                if (obj != null) {
                                    if (obj.isOnScreen()) {
                                        camera.turnToObject(obj);
                                    }
                                }
                            }
                            break;
                            case 17: {
                                RSObject Bank = objects.getNearest(locations.bankBoothID());
                                if (Bank != null) {
                                    if (bank != null && !bank.isOpen()) {
                                        if (Bank.isOnScreen()) {
                                            camera.turnToObject(Bank);
                                        }
                                    }
                                }
                            }
                            break;
                        }
                    }
                    switch (rand) {
                        case 18: {
                            if (canAntiBan && !cameraChecker.movedRecently() && !mouseChecker.movedRecently()) {
                                ab.wiggleMouse();
                            }
                        }
                        break;
                        case 19: {
                            if (canAntiBan && !cameraChecker.movedRecently() && !mouseChecker.movedRecently()) {
                                moveMouseRandomly(random(20, 200));
                                if (random(1, 2) == 1) {
                                    camera.setPitch(false);
                                } else {
                                    camera.setPitch(true);
                                }
                            }
                        }
                        break;
                        case 20: {
                            if (canAntiBan && !cameraChecker.movedRecently() && !mouseChecker.movedRecently()) {
                                ab.camera();
                            }
                        }
                        break;
                        case 22: {
                            if (canAntiBan && !cameraChecker.movedRecently() && !mouseChecker.movedRecently()) {
                                ab.camera();
                                ab.wiggleMouse();
                            }
                        }
                        break;
                    }
                    sleep(random(200, 400));
                    if (rand >= random(98, 102)) {
                        mouse.setSpeed(random(mouseLo, mouseHi));
                    }
                }
                sleep(random(600, 800));
            }
        }
    }

    private class CameraMovementChecker implements Runnable {

        private int x = 0, y = 0, z = 0;
        private boolean movement = false;

        private void sleep(int t) {
            try {
                Thread.sleep(t);
            } catch (Exception e) {
            }
        }

        public void run() {
            while (running) {
                try {
                    x = camera.getX();
                    y = camera.getY();
                    z = camera.getZ();
                    if (camera.getX() != x || camera.getY() != y || camera.getZ() != z) {
                        movement = true;
                    } else {
                        movement = false;
                    }
                    sleep(random(200, 300));
                    if (camera.getX() != x || camera.getY() != y || camera.getZ() != z) {
                        movement = true;
                    } else {
                        movement = false;
                    }
                } catch (Exception e) {
                }
            }
        }

        public boolean movedRecently() {
            return movement;
        }
    }

    private class failSafe implements Runnable {

        private boolean failsafe = false;
        private boolean edit = true;

        public failSafe() {
            new Thread(this).start();
        }

        private void sleep(int t) {
            try {
                Thread.sleep(t);
            } catch (Exception e) {
            }
        }

        public void run() {
            while (running) {
                if (edit) {
                    failsafe = false;
                }
                edit = true;
                try {
                    if (game.isLoggedIn() && !game.isWelcomeScreen() && !game.isLoginScreen() && !isPaused() && isRunning() && isActive()) {
                        this.sleep(random(4000, 7500));
                        if (utilThread.getIdle() >= 275) {
                            failsafe = true;
                        }
                        if (System.currentTimeMillis() - mouse.getPressTime() >= 50000) {
                            failsafe = true;
                        }
                        if (!locations.bankArea().contains(getMyPlayer().getLocation()) && !locations.waterArea().contains(getMyPlayer().getLocation())) {
                            if (!getMyPlayer().isMoving()) {
                                this.sleep(random(200, 400));
                                if (!getMyPlayer().isMoving() && !locations.fullArea().contains(getMyPlayer().getLocation())) {
                                    failsafe = true;
                                }
                            }
                        }
                        if (failsafe) {
                            int random = random(1, 10);
                            switch (random) {
                                case 1: {
                                    mouse.moveRandomly(random(100, 200));
                                    camera.moveRandomly(random(400, 450));
                                    camera.setPitch(false);
                                }
                                break;
                                case 2: {
                                    camera.setPitch(true);
                                    camera.setAngle(random(120, 250));
                                    camera.moveRandomly(random(random(50, 70), 500));
                                }
                                break;
                                case 3: {
                                    camera.setPitch(false);
                                    mouse.moveSlightly();
                                    mouse.moveSlightly();
                                    camera.moveRandomly(random(100, 150));
                                    mouse.moveSlightly();
                                }
                                break;
                                case 4: {
                                    mouse.moveOffScreen();
                                    camera.moveRandomly(random(200, 400));
                                    if (random(1, 2) == 1 || camera.getPitch() <= 92) {
                                        camera.setPitch(true);
                                    }
                                    camera.moveRandomly(random(100, 250));
                                }
                                break;
                                case 5: {
                                    camera.setPitch('w');
                                    camera.moveRandomly(random(200, 400));
                                }
                                break;
                                case 6: {
                                    camera.moveRandomly(random(100, 240));
                                    mouse.moveSlightly();
                                    camera.setPitch(true);
                                }
                                break;
                            }
                            if (random >= 7) {
                                if (locations.waterArea().contains(getMyPlayer().getLocation())) {
                                    RSObject water;
                                    if (string) {
                                        water = objects.getNearest(locations.waterName());
                                    } else {
                                        water = objects.getNearest(locations.waterID());
                                    }
                                    if (water != null) {
                                        camera.turnToObject(water);
                                        if (random(1, 2) == 2) {
                                            camera.setPitch(false);
                                        } else {
                                            camera.setPitch(true);
                                        }
                                    }
                                } else if (locations.waterArea().contains(getMyPlayer().getLocation())) {
                                    RSObject bank = objects.getNearest(locations.bankBoothID());
                                    if (bank != null) {
                                        camera.turnToObject(bank);
                                    }
                                } else {
                                    failsafe = true;
                                    edit = false;
                                }
                            }
                            int random2 = random(1, 3);
                            if (random2 == 1) {
                                camera.setPitch(true);
                                camera.setCompass('e');
                            } else if (random2 == 2) {
                                camera.setCompass('w');
                                if (random(1, 3) >= 2) {
                                    camera.setPitch(true);
                                }
                            } else {
                                mouse.move(calc.tileToScreen(locations.fountainTile(), 0.5, 0.5, 0));
                                if (random(1, 3) == 1) {
                                    camera.setPitch(true);
                                }
                                if (random(1, 2) == 1) {
                                    camera.setCompass('e');
                                } else {
                                    camera.setCompass('w');
                                }
                                if (camera.getPitch() <= 99) {
                                    camera.setPitch(true);
                                }
                            }
                            camera.moveRandomly(random(400, 600));
                            if (edit) {
                                failsafe = false;
                            }
                        }
                    }
                } catch (Exception e) {
                }
            }
        }
    }

    private class MouseMovementChecker implements Runnable {

        private boolean movement = false;
        private long time = 0, mouseTime = 0;
        private Point mousePoint = new Point(-1, -1);

        private void sleep(int t) {
            try {
                Thread.sleep(t);
            } catch (Exception e) {
            }
        }

        public MouseMovementChecker() {
            new Thread(this).start();
        }

        public void run() {
            while (running) {
                try {
                    time = System.currentTimeMillis();
                    mouseTime = mouse.getPressTime();
                    mousePoint = mouse.getLocation();
                    if (time - mouseTime <= 900) {
                        movement = true;
                    } else {
                        movement = false;
                    }
                    sleep(random(100, 150));
                    if (System.currentTimeMillis() - mouseTime >= 1100) {
                        movement = false;
                    } else {
                        movement = true;
                    }
                    sleep(random(200, 150));
                    if (System.currentTimeMillis() - mouseTime >= 1225) {
                        movement = false;
                    } else {
                        movement = true;
                    }
                    if (!mousePoint.equals(mouse.getLocation())) {
                        movement = true;
                    } else {
                        movement = false;
                    }
                    if (System.currentTimeMillis() - mouse.getPressTime() >= 1000) {
                        movement = false;
                    } else {
                        movement = true;
                    }
                } catch (Exception e) {
                }
            }
        }

        public boolean movedRecently() {
            return movement;
        }
    }

    private class Timekeeper {

        long startTime = System.currentTimeMillis();
        long pausedTime = 0;
        long pausedTemp = 0;
        int state = 0;

        public int getState() {
            return state;
        }

        private void setPausedTime(long setTime) {
            pausedTime += setTime;
        }

        private long getPausedTime() {
            if (pausedTemp != 0) {
                return (System.currentTimeMillis() - pausedTemp);
            } else {
                return 0;
            }
        }

        public long getMillis() {
            if (state == 1) {
                return System.currentTimeMillis() - startTime - getPausedTime();
            } else {
                return System.currentTimeMillis() - startTime - pausedTime;
            }
        }

        public long getSeconds() {
            return this.getMillis() / 1000;
        }

        public long getMinutes() {
            return this.getSeconds() / 60;
        }

        public long getHours() {
            return this.getMinutes() / 60;
        }

        public String getRuntimeString() {
            StringBuilder builder = new StringBuilder();
            long HoursRan = this.getHours();
            long MinutesRan = this.getMinutes();
            long SecondsRan = this.getSeconds();
            MinutesRan = MinutesRan % 60;
            SecondsRan = SecondsRan % 60;
            if (HoursRan < 10) {
                builder.append("0");
            }
            builder.append(HoursRan);
            builder.append(":");
            if (MinutesRan < 10) {
                builder.append("0");
            }
            builder.append(MinutesRan);
            builder.append(":");
            if (SecondsRan < 10) {
                builder.append("0");
            }
            builder.append(SecondsRan);
            return builder.toString();
        }

        public void setPaused() {
            state = 1;
            pausedTemp = System.currentTimeMillis();
        }

        public void setResumed() {
            state = 0;
            this.setPausedTime(this.getPausedTime());
            pausedTemp = 0;
        }

        public long calcPerHour(final long i) {
            return calcPerHour((double) i);
        }

        public long calcPerHour(final double i) {
            final double elapsed_millis = this.getMillis();
            return (long) ((i / elapsed_millis) * 3600000);
        }

        public double calcPerSecond(final long i) {
            final double expToDouble = i;
            final double elapsed_millis = this.getMillis();
            return (expToDouble / elapsed_millis) * 1000;
        }
    }

    private class UtilThread implements Runnable {

        private long idleTime = 0;

        private void sleep(int t) {
            try {
                Thread.sleep(t);
            } catch (final Exception e) {
            }
        }

        public long getIdle() {
            return idleTime;
        }

        public void reset(long t) {
            idleTime = t;
        }

        public UtilThread() {
            new Thread(this).start();
        }

        public void run() {
            int lastCount = 0;
            while (running) {
                sleep(90);
                if (isPaused()) {
                    continue;
                }
                if (lastCount > inventory.getCount(item.emptyID()) && lastCount != 0) {
                    numDone++;
                }
                lastCount = inventory.getCount(item.emptyID());
                if (players.getMyPlayer().getAnimation() == -1 && !players.getMyPlayer().isMoving() && players.getMyPlayer().getAnimation() != 11786) {
                    idleTime++;
                } else {
                    idleTime = 0;
                }
                sleep(10);
            }
        }
    }
	
	public class Updater {

    private URLConnection url = null;
    private BufferedReader in = null;
    private FileDownLoader fdl = null;

    public boolean checkUpdate(double Ver, String scriptName) {
        try {
            url = new URL("http://aut0rprogramming.net/"+scriptName+"/"+scriptName+".txt").openConnection();
            in = new BufferedReader(new InputStreamReader(url.getInputStream()));
            if (Double.parseDouble(in.readLine()) > Ver) {
                if (JOptionPane.showConfirmDialog(null, "Do you want to update now?", "Update found",
                        JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == 0) {
                    JOptionPane.showMessageDialog(null, "Save this file as "+scriptName+".jar in 'RSBot/Scripts/Precompiled'");
                    fdl = new FileDownLoader();
                    if (fdl.saveUrl("http://aut0rprogramming.net/"+scriptName+"/"+scriptName+".jar", scriptName)) {
                        JOptionPane.showMessageDialog(null, "Update complete, you MUST reload RSBot, and make sure "+scriptName+".jar file is in the Precompiled folder!");
                        return false;
                    }
                } else {
                    return false;
                }
            } else {
                return true;
            }
        } catch (IOException e) {
        }
        return false;
    }
	}

public class FileDownLoader {
    private JFileChooser jfc;
    public boolean saveUrl(String urlString, String scriptName) throws MalformedURLException, IOException {
        BufferedInputStream in = null;
        FileOutputStream fout = null;
        File revision = new File(scriptName+".jar");
        jfc = new JFileChooser();
        jfc.setSelectedFile(revision);
        if(jfc.showSaveDialog(null) == JFileChooser.APPROVE_OPTION){
            try {
                File selectedFile = jfc.getSelectedFile();
                in = new BufferedInputStream(new URL(urlString).openStream());
                fout = new FileOutputStream(selectedFile);
                byte data[] = new byte[1024];
                int count;
                while ((count = in.read(data, 0, 1024)) != -1) {
                    fout.write(data, 0, count);
                }
            }
            finally {
                if (in != null)
                        in.close();
                if (fout != null)
                        fout.close();
            }
            return true;
        } else {
            return false;
        }
    }
}
}
